package com.example.service;

import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.model.output.Response;
import com.example.config.AiConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.http.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;

@Service
@Slf4j
public class OpenAiService {
    
    private static final Logger log = LoggerFactory.getLogger(OpenAiService.class);
    
    @Autowired
    private ChatLanguageModel chatModel;
    
    @Autowired
    private OpenAiStreamingChatModel streamingModel;
    
    @Autowired
    private AiConfig aiConfig;
    
    public String getAnswer(String question) {
        String promptTemplate = "你是一个专业的java开发工程师，我将要问你问题。请详细回答以下问题："+question;
        
        PromptTemplate template = PromptTemplate.from(promptTemplate);
        Prompt prompt = template.apply(Map.of("question", question));
        
        try {
            System.out.println("prompt.text():"+prompt.text());
            return chatModel.generate(prompt.text());
        } catch (Exception e) {
            if (e.getCause() instanceof java.io.InterruptedIOException) {
                return "抱歉，AI服务响应超时，请稍后重试。";
            }
            e.printStackTrace();
            return "抱歉，AI服务暂时无法回答，请稍后再试。错误信息：" + e.getMessage();
        }
    }
    
    public List<String> analyzeTopicKeywords(String topic) {
        String promptTemplate = """
            请分析以下主题或问题的关键技术点，提取3-5个关键词，用逗号分隔输出。
            只需要输出关键词，不要其他任何解释。
            
            主题：%s
            """.formatted(topic);
        
        try {
            String response = chatModel.generate(promptTemplate);
            return Arrays.asList(response.trim().split("，|,"));
        } catch (Exception e) {
            if (e.getCause() instanceof java.io.InterruptedIOException) {
                return Arrays.asList("服务超时");
            }
            e.printStackTrace();
            return Arrays.asList(topic.split("\\s+"));
        }
    }
    
    public List<String> analyzeResume(String resumeContent) {
        String promptTemplate = """
            作为一位资深的技术面试官，请分析以下简历内容，提取关键技术点和项目经验，
            并生成一系列针对性的面试问题。每个问题需要覆盖以下维度：
            1. 技术深度
            2. 项目经验
            3. 系统设计
            4. 问题解决能力
            
            简历内容：
            {resumeContent}
            
            请以JSON格式返回，包含以下字段：
            - topics: 需要重点准备的技术主题
            - questions: 面试问题列表，每个问题包含difficulty和type字段
            """;
        
        try {
            String response = chatModel.generate(promptTemplate.replace("{resumeContent}", resumeContent));
            return parseResumeAnalysis(response);
        } catch (Exception e) {
            log.error("Failed to analyze resume", e);
            throw new RuntimeException("简历分析失败");
        }
    }
    
    public String generateLearningPath(String topic) {
        String promptTemplate = """
            作为一位资深Java开发工程师，请为以下技术主题制定详细的学习路径：
            {topic}
            
            请包含：
            1. 必备基础知识
            2. 进阶概念
            3. 实践项目建议
            4. 常见面试问题
            5. 学习资源推荐
            """;
            
        return chatModel.generate(promptTemplate.replace("{topic}", topic));
    }
    
    public String getInterviewFeedback(String question, String answer) {
        String promptTemplate = """
            作为面试官，请对以下面试问题的回答进行评估：
            
            问题：{question}
            答案：{answer}
            
            请从以下维度进行点评：
            1. 回答的完整性
            2. 技术准确性
            3. 表达清晰度
            4. 改进建议
            """;
            
        return chatModel.generate(promptTemplate
            .replace("{question}", question)
            .replace("{answer}", answer));
    }

    private List<String> parseResumeAnalysis(String response) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode root = mapper.readTree(response);
            
            List<String> result = new ArrayList<>();
            
            // 解析技术主题
            if (root.has("topics")) {
                JsonNode topics = root.get("topics");
                if (topics.isArray()) {
                    for (JsonNode topic : topics) {
                        result.add(topic.asText());
                    }
                }
            }
            
            return result;
        } catch (Exception e) {
            log.error("Failed to parse resume analysis", e);
            throw new RuntimeException("解析简历分析结果失败", e);
        }
    }

    public SseEmitter streamAnswer(String question) {
        SseEmitter emitter = new SseEmitter(180000L);
        
        try {
            String promptTemplate = "你是一个专业的java开发工程师，请详细回答以下问题(如果我问的不是Java技术问题，那么就正常对话方式回答就好，不要总是给我建议，要像人类一样对话就好)：" + question;
            
            new Thread(() -> {
                try {
                    streamingModel.generate(UserMessage.from("user", promptTemplate),
                        new StreamingResponseHandler<AiMessage>() {
                            @Override
                            public void onNext(String s) {
                                try {
                                    if (s != null && !s.isEmpty()) {
                                        emitter.send(SseEmitter.event()
                                                .data(s)
                                                .build());
                                    }
                                } catch (Exception e) {
                                    log.error("Error sending message chunk", e);
                                    onError(e);
                                }
                            }

                            @Override
                            public void onComplete(Response<AiMessage> response) {
                                try {
                                    // 发送完成事件
                                    emitter.send(SseEmitter.event()
                                            .name("complete")
                                            .data("")
                                            .build());
                                    // 完成SSE流
                                    emitter.complete();
                                    log.info("Stream completed successfully");
                                } catch (Exception e) {
                                    log.error("Error in onComplete", e);
                                    onError(e);
                                }
                            }

                            @Override
                            public void onError(Throwable error) {
                                log.error("Streaming error", error);
                                try {
                                    emitter.send(SseEmitter.event()
                                            .name("error")
                                            .data("AI服务出错，请重试")
                                            .build());
                                } catch (Exception e) {
                                    log.error("Error sending error event", e);
                                }
                                emitter.completeWithError(error);
                            }
                        });
                } catch (Exception e) {
                    log.error("Stream generation error", e);
                    emitter.completeWithError(e);
                }
            }).start();
            
            emitter.onCompletion(() -> log.info("Stream completed"));
            emitter.onTimeout(() -> log.warn("Stream timeout"));
            emitter.onError((ex) -> log.error("Stream error", ex));
            
        } catch (Exception e) {
            log.error("Failed to create streaming response", e);
            emitter.completeWithError(e);
        }
        
        return emitter;
    }
} 